package com.winner.visitor_pattern;

/**
 * 访问者模式（Visitor Pattern）是一种行为型设计模式，它可以在不改变对象结构的前提下定义作用于这些对象元素的新操作。
 * 该模式通过在访问者对象中添加访问元素的方法，使得可以在不修改每个元素类的情况下，为元素类添加新的操作。
 *
 * 多态accept方法
 *
 * 在这个示例中：
 *
 * Element 是元素接口，定义了一个接受访问者访问的方法 accept。
 * ConcreteElementA 和 ConcreteElementB 是具体元素类，实现了 Element 接口，并分别实现了自己的 operation 方法。
 * Visitor 是访问者接口，定义了访问具体元素的方法。
 * ConcreteVisitor 是具体访问者类，实现了 Visitor 接口，并实现了访问具体元素的方法。
 * Client 是客户端类，创建了具体元素对象和访问者对象，并将具体元素接受访问者的访问。
 * 访问者模式可以有效地解耦元素与操作，使得新增操作时不需要修改元素类，只需要新增具体访问者类即可。
 *
 * @Author wangxinle5
 * @since 2024-04-23
 */
// 客户端类
public class Client {
    public static void main(String[] args) {
        // 创建具体元素对象
        Element elementA = new ConcreteElementA();
        Element elementB = new ConcreteElementB();

        // 创建访问者对象
        Visitor visitor = new ConcreteVisitor();

        // 元素接受访问者访问
        elementA.accept(visitor); // 输出：ConcreteElementA operation
        elementB.accept(visitor); // 输出：ConcreteElementB operation
    }
}

// 元素接口
interface Element {
    void accept(Visitor visitor);
}

// 具体元素类 A
class ConcreteElementA implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public void operationA() {
        System.out.println("ConcreteElementA operation");
    }
}

// 具体元素类 B
class ConcreteElementB implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public void operationB() {
        System.out.println("ConcreteElementB operation");
    }
}

// 访问者接口
interface Visitor {
    void visit(ConcreteElementA element);
    void visit(ConcreteElementB element);
}

// 具体访问者类
class ConcreteVisitor implements Visitor {
    @Override
    public void visit(ConcreteElementA element) {
        element.operationA();
    }

    @Override
    public void visit(ConcreteElementB element) {
        element.operationB();
    }
}


